/**
 * @addtogroup FXDRM
 * @{
 */

/**
 * @file
 * @brief Timestamp algorithms
 */

#ifndef _FXPKI_TIMESTAMP_H_
#define _FXPKI_TIMESTAMP_H_

#ifdef __cplusplus
extern "C" {
#endif



// Timestamp_request handler.
FX_DEFINEHANDLE(FXPKI_TIMESTAMP_Request)
// Timestamp_response handler
FX_DEFINEHANDLE(FXPKI_TIMESTAMP_Response)
// Timestamp_config_file handler.
FX_DEFINEHANDLE(FXPKI_TIMESTAMP_Configer)

//////////////////////////////////////////////////////////////////////////////////////////////////
// Request
/////////////////////////////////////////////////////////////////////////////////////////////////

/** 
 * @brief Creates a timestamp_request.
 *
 * @param[in]	digestData		The digest of the data for which the time stamp request needs to be created.
 * @param[in]	digestLen		The digest length.
 * @param[in]	digest			Digest algorithm to apply to the data file. For details please see menu _FX_DIGEST_TYPE.
 * @param[out]	request			The timestamp request handler.
 * @return TRUE for success<br>
 *		   FALSE for failure.
 *		   FALSE if parameter <i>digestData</i> or <i>request</i> is a <b>NULL</b> pointer.
 * @note After useing this request handler, which need be freed by FXPKI_TIMESTAMP_ReleaseRequest().
 */
FX_BOOL     FXPKI_TIMESTAMP_CreateRequest(FX_LPCBYTE digestData, FX_INT32 digestLen, FX_DIGEST_TYPE digestAlgo, FXPKI_TIMESTAMP_Request* request);

/** 
 * @brief Frees the timestamp request.
 *
 * @param[in]	request			The handler of the timestamp request.
 */
void		FXPKI_TIMESTAMP_ReleaseRequest(FXPKI_TIMESTAMP_Request request);

/** 
 * @brief Sets policy for the timestamp request. Optional.
 *
 * @param[in]	request			The request handler need to be set.
 * @param[in]	policy			The policy OID that the client expects the TSA to use for creating the time stamp token. The OID can be specified in dotted notation. If no policy is requested the TSA will use its own default policy.
 * @return TRUE for success,<br>
 *		   FALSE for failure. <br>
 *		   FALSE if parameter <i>request</i> is a <b>NULL</b> pointer.
 */
FX_BOOL		FXPKI_TIMESTAMP_SetRequestPolicy(FXPKI_TIMESTAMP_Request request, FX_LPCSTR policy);

/** 
 * @brief Sets nonce for the timestamp request. Optional.
 *
 * @param[in]	request			The request handler need to be set.
 * @param[in]	nBits			Nonce length. No nonce is specified in the request if nBits less than or equal to 0, or nBits more than 160.
 * @return TRUE for success,<br>
 *		   FALSE for failure. <br>
 *		   FALSE if parameter <i>request</i> is a <b>NULL</b> pointer.
 */
FX_BOOL		FXPKI_TIMESTAMP_SetRequestSeedBit(FXPKI_TIMESTAMP_Request request, FX_INT32 nBits);

/** 
 * @brief Sets if expect the TSA include its certs in the response. Optional.
 *
 * @param[in]	request			The request handler need to be set.
 * @param[in]	state			If the TSA is expected to include its certs in the response.
 * @return TRUE for success,<br>
 *		   FALSE for failure. <br>
 *		   FALSE if parameter <i>request</i> is a <b>NULL</b> pointer.
 */
FX_BOOL		FXPKI_TIMESTAMP_SetRequestCertState(FXPKI_TIMESTAMP_Request request, FX_BOOL state);

/** 
 * @brief Gets the content from the timestamp request.
 *
 * @param[in]	request			The request handler.
 * @param[out]	buf				The buffer, to which the request content will be written.
 * @param[out]	len				The content length.
 * @return TRUE for success,<br>
 *		   FALSE for failure. <br>
 *		   FALSE if parameter <i>request</i>, <i>buf</i> or <i>len</i> is a <b>NULL</b> pointer.
 * @note After useing this buffer, we need to free it by FX_Free().
 */
FX_BOOL		FXPKI_TIMESTAMP_GetRequestContent(FXPKI_TIMESTAMP_Request request, FX_LPBYTE* buf, FX_INT32* len);

//////////////////////////////////////////////////////////////////////////////////////////////////
// Verify
/////////////////////////////////////////////////////////////////////////////////////////////////

/** 
 * @brief Create response handler by reading response in DER format.
 *
 * @param[in]	responseBuf		The timestamp response in DER format.
 * @param[in]	responseLen		Length of the response content.
 * @param[out]	response		The response handler.
 * @return TRUE for success. <br>
 *		   FALSE for failure. <br>
 *		   FALSE if parameter <i>responseBuf</i> is a <b>NULL</b> pointer.
 * @note After using this response handler, we need to free it by calling FXPKI_TIMESTAMP_ReleaseResponse.
 */
FX_BOOL		FXPKI_TIMESTAMP_CreateResponseFromData(FX_LPCBYTE responseBuf, FX_INT32 responseLen, FXPKI_TIMESTAMP_Response* response);

/** 
 * @brief Release response handler.
 *
 * @param[in]	response		The response handler.
 */
void		FXPKI_TIMESTAMP_ReleaseResponse(FXPKI_TIMESTAMP_Response response);

/** 
 * @brief Check if the response contains certs.
 *
 * @param[in]	response		The response handler.
 * @return If it containing certs then return TRUE, <br>
 *		   else return FALSE. <br>
 */
FX_BOOL     FXPKI_TIMESTAMP_HasCert(FXPKI_TIMESTAMP_Response response);

/** 
 * @brief Get signer certificate and cert list from response specified.
 *
 * @param[in]	response		The response handler.
 * @param[out]	x509			Obtain signer cert.
 * @param[out]	list			Obtain cert list.
 * @return TRUE for success, <br>
 *		   else FALSE. <br>
 */
FX_BOOL		FXPKI_TIMESTAMP_GetResponseCertList(FXPKI_TIMESTAMP_Response response, FX_X509* x509, FX_CERTLIST* list);
    
/** 
 * @brief Verifies if a time stamp response is valid.
 *
 * @param[in]	response		The timestamp response handler that needs to be verified in DER format.
 * @param[in]	store			The store containing trusted CA cert and CRL.
 * @param[in]	digestData		The digest which against the response.
 * @param[in]	digestLen		The digest data length.
 * @param[in]	untrustedCerts	A group of certs which may be needed when building the certificate chain for the TSA's signing certificate. It can be passed NULL if response contains cert chain.
 * @return TRUE if verification is successful <br>
 *		   otherwise return FALSE. <br>
 *		   FALSE if parameter <i>response</i>, <i>store</i> or <i>digestData</i> is a <b>NULL</b> pointer.
 */
FX_BOOL		FXPKI_TIMESTAMP_Verify(FXPKI_TIMESTAMP_Response response, FX_CERTSTORE store, FX_LPCBYTE digestData, FX_INT32 digestLen, FX_CERTLIST certlist);

// Request item types
typedef enum _FX_REQ_ITEMTYPE
{
	FX_REQ_VERSION = 0,
	FX_REQ_HASH_ALGORITHM,
	FX_REQ_MESSAGE_DATA,
	FX_REQ_POLICY_OID,
	FX_REQ_NONCE,
	FX_REQ_CERT_STATE,
	FX_REQ_EXTENSIONS,
} FX_REQ_ITEMTYPE;

/** 
 * @brief Extract the item data of the timestamp request.
 *
 * @param[in]	request			The timestamp request handler.
 * @param[in]	reqType			The data type to extract. For details please see menu _FX_REQ_ITEMTYPE.
 * @param[out]	textBuf			The data.
 *								<b>NOTE</b>: After useing this buffer, it need to be freed by FX_Free().
 * @param[out]	textLen			The data length in bytes.
 * @return TRUE for success <br>
 *		   otherwise return FALSE. <br>
 *		   FALSE if parameter <i>request</i>, <i>textBuf</i> or <i>textLen</i> is a <b>NULL</b> pointer.
 */
FX_BOOL		FXPKI_TIMESTAMP_GetRequestItemData(FXPKI_TIMESTAMP_Request request, FX_REQ_ITEMTYPE reqType, FX_LPBYTE* textBuf, FX_INT32* textLen);

// Response item types
typedef enum _FX_RESP_ITEMTYPE
{
	FX_RESP_STATUS = 0,
	FX_RESP_VERSION,
	FX_RESP_HASH_ALGORITHM,
	FX_RESP_MESSAGE_DATA,
	FX_RESP_POLICY_OID,
	FX_RESP_SERIAL_NUMBER,
	FX_RESP_TIME_STAMP,
	FX_RESP_ACCURACY,
	FX_RESP_ORDERING,
	FX_RESP_NONCE,
	FX_RESP_TSA_NAME,
	FX_RESP_EXTENSIONS,
	FX_RESP_SIGNER_CERT,
} FX_RESP_ITEMTYPE;

/** 
 * @brief Extract the timestamp response item data.
 *
 * @param[in]	response		The timestamp response handler.
 * @param[in]	respType		The item type to extract. For details please see menu _FX_RESP_COMPONENT.
 * @param[out]	textBuf			The item content.
 *								<b>NOTE</b>: After useing this buffer, it need to be freed by FX_Free().
 * @param[out]	textLen			The content length in bytes.
 * @return TRUE for success <br>
 *		   otherwise return FALSE.
 */
FX_BOOL		FXPKI_TIMESTAMP_GetResponseItemData(FXPKI_TIMESTAMP_Response response, FX_RESP_ITEMTYPE respType, FX_LPBYTE* textBuf, FX_INT32* textLen);

#ifdef __cplusplus
};
#endif

#endif	// _FXPKI_TIMESTAMP_H_

/** @} */